
local japi = require 'jass.japi'
local jass = require 'jass.common'

local IsWindowActive = japi.IsWindowActive

local function get_collision(widget)
    if widget.get_collision then 
        return widget:get_collision()
    end
    return 32.0
end 

local function get_model_scale(widget)
    if not widget.get_slk then 
        return 1
    end 
    return widget:get_slk ('scale', 1.0)
end 

local function get_scale(widget)
    if widget.get_scale then 
        return widget:get_scale()
    end 
    return 1
end 

local function unit_overhead(widget)
    if widget.type == 'unit' then 
        return ac.message.unit_overhead(widget.handle)
    end 
    return 80
end 

local function get_height(widget)
    if widget.get_height then 
        return widget:get_height()
    end 
    return 0
end 

local function get_limit_height(widget)
    if widget.get_limit_height then 
        return widget:get_limit_height()
    end 
    return 0
end 

local function get_xyz(widget)
    local x, y, z = 0, 0, 0
    if widget.handle then 
        if widget.get_anchor_point then 
            x, y = widget:get_anchor_point()
        else
            x = jass.GetWidgetX(widget.handle)
            y = jass.GetWidgetY(widget.handle)
        end
        z = ac.point.get_location_height(x, y) + get_height(widget) + unit_overhead(widget)
    end 
    return x, y, z
end 

--- 单位是否处于世界控件内
--- 装载 吞噬 等等其他隐藏情况自行判断
function ac.unit.__index:in_worldscreen()
    return not self.removed 
    and self:is_visible(ac.player.self) 
    and self:is_alive() 
    and (not self:is_hidden())
    and (not self:is_loaded()) 
    and (not self:has_restriction "蝗虫")
end

--- 物品是否处于世界控件内
--function ac.item.__index:in_worldscreen()
--    return not self.removed 
--    and not (self.owner) 
--    and self:is_visible() 
--    and self:is_alive() 
--end

local mt = ac.frame

-- 世界标准宽
mt.world_width = 90

-- 世界标准高
mt.world_height = 10

-- 世界标准缩放
mt.world_scale = 1.0

-- 自动删除 不建议用
mt.world_auto_remove = false 

-- 锚点位置
mt.world_anchor = "bottom"

local worldanchor = {}

worldanchor.controls = {}

function mt:bind_world(object)
    if self.removed then return end
    if not object then return end
    self.world_widget = object
    worldanchor.controls[self.handle] = self
end 

function mt:unbind_world()
    if not self.world_widget then return end
    self.world_widget = nil 
    worldanchor.controls[self.handle] = nil 
end

function mt:on_world_update()

end

worldanchor.update = function()
    if not IsWindowActive() then return end;
    for _, frame in pairs(worldanchor.controls) do 
        local widget = frame.world_widget
        if widget.removed and frame.world_auto_remove then
            frame:hide()
            frame:unbind_world()
            frame:remove()
        else 
            if widget:in_worldscreen() then 
                local x, y, z = get_xyz(widget)
                local screen_x, screen_y = ac.frame.w2s(x, y, z)
                if screen_x == nil or screen_x < 0 or screen_y < 32 or screen_x > 1920 or screen_y > 768 then 
                    frame:hide()
                else 
                    local scale = 1
                    if frame.world_auto_size then
                        scale = get_model_scale(widget)
                        frame.world_scale = scale
                        frame:set_width(frame.world_width * scale, frame.world_height)
                    end
                    frame:set_real_position(screen_x - frame.w, screen_y - frame.h + 35, frame.world_anchor)
                    frame:on_world_update(widget, scale)
                    frame:show()
                end 
            else
                frame:hide()
            end 
        end 
    end 
end

ac.hardware:on '界面绘制' (worldanchor.update)

return worldanchor
